import React from 'react';
import PropTypes from 'prop-types';
import {Tree, Spin, Icon} from 'antd';
import {injectIntl} from './intl';
const TreeNode = Tree.TreeNode;
import {union} from 'lodash';
import styles from './CategoryTree.css';
import {workItemCategoryStatus} from '../Enum';
const calcLink = (id, pages, paths) => {
    if(!id)
        return;
    for(let i = 0; i < pages.length; i++)
        /*eslint-disable  eqeqeq*/
        if(pages[i].id == id || (pages[i].items && calcLink(id, pages[i].items, paths))) {
            paths.push(`${pages[i].id}`);
            return true;
        }
};

export class CategoryTree extends React.PureComponent {
    static getDerivedStateFromProps(props, state) {
        if(props.locatedKey === state.locatedKey)
            return null;
        if(!props.locatedKey)
            return {locatedKey: null};
        const link = [];
        calcLink(props.locatedKey, props.pages, link);
        if(link.length === 0)
            return null;
        return {
            locatedKey: props.locatedKey,
            expandedKeys: union(state.expandedKeys, link.slice(1))
        };
    }
    constructor(props) {
        super(props);
        const link = [];
        this.state = {
            locatedKey: props.locatedKey ? props.locatedKey.toString() : '',
            expandedKeys: (props.locatedKey && calcLink(props.locatedKey, props.pages, link)) ? link.slice(1) : [],
            isReload: false,
            loading: false,
        };
        this.onExpand = this.onExpand.bind(this);
        this.onSelect = this.onSelect.bind(this);
        this.onLoadData = this.onLoadData.bind(this);
        this.renderTreeNodes = this.renderTreeNodes.bind(this);
    }
    

    componentDidMount() {
        this.props.init();
    }
    renderTreeNodes(data = []) {
        const _ = this;
        return data.map(item => {
            const {items = []} = item;
            return (<TreeNode key={item.id}
                title={item.code ? `${item.name}(${item.code})` : item.name}
                dataRef={item}
                isLeaf={item.isLeaf}
                selectable={_.props.selectable(item)}>
                {!item.isLeaf && this.renderTreeNodes(items.filter(p => p.status === workItemCategoryStatus.生效))}
            </TreeNode>);
        });
    }

    onExpand(expandedKeys, {expanded, node}) {
        this.setState({expandedKeys});
        if(expanded && this.state.isReload)
            this.onLoadData(node).then(() => {
                this.setState({isReload: false});
            });
    }

    onSelect(selectedKeys, e) {
        const id = e.selected ? selectedKeys[0] : this.props.locatedKey.toString();
        if(id !== this.props.locatedKey.toString())
            this.props.onSelect(id, e.node.props.dataRef);
    }

    onLoadData(node) {
        const data = node.props.dataRef;
        return data.items && data.items.length
            ? Promise.resolve()
            : this.props.onLoadData(data);
    }

    onReload = () => {
        this.props.onReload();
        this.setState({
            expandedKeys: [],
            isReload: true
        });
    }
    render() {
        return (
            <Spin spinning={this.props.loading}>
                <div className={styles.button}>
                    <a title={this.props.intl.formatMessage({
                        id: 'categoryTree.btn.reload',
                        defaultMessage: '刷新'
                    })}><Icon type="reload" onClick={this.onReload} /></a>
                </div>
                <Tree loadData={this.onLoadData} onExpand={this.onExpand} onSelect={this.onSelect}
                    expandedKeys={this.state.expandedKeys}
                    selectedKeys={this.props.locatedKey ? [this.props.locatedKey.toString()] : null}
                    autoExpandParent={false}>
                    {this.renderTreeNodes(this.props.pages)}
                </Tree>
            </Spin>
        );
    }
}

/**
 * 树形结构展示CategoryTree
 */
CategoryTree.propTypes = {
    /**
     * 页面数据
     * pages: [{
     *      id: required,
     *      items: pages,    子节点
     *      name: required,     名称
     *      code: required,     编号
     *      isLeaf: required, 是否叶子节点
     * }]
     * }
     */
    init: PropTypes.func,
    /**
     * 展开节点需要异步获取数据时触发
     * @param node  节点数据
     */
    intl: PropTypes.object,
    /**
     * 选中节点时触发
     * @param id  当前选中节点的id
     */
    loading: PropTypes.bool,
    locatedKey: PropTypes.oneOfType([
        PropTypes.string,
        PropTypes.number
    ]),
    pages: PropTypes.array,
    /**
     * 设置节点是否可选择
     * @default true 默认可选中
     */
    selectable: PropTypes.func,
    onLoadData: PropTypes.func,
    onReload: PropTypes.func,
    onSelect: PropTypes.func,
};

CategoryTree.defaultProps = {
    pages: [],
    locatedKey: '',
    onLoadData: () => Promise.resolve(),
    onSelect: () => Promise.resolve(),
    selectable: () => true
};


import {
    getCategoryChildren,
    categoryHighSearch,
    getTopCategories,
    saveHighQueryCondition
} from './actions';

import {connect} from 'react-redux';
import selectorFactory from 'Shared/utils/immutableToJsSelectorFactory';
import {createSelector} from 'reselect';
import {getObjById} from './utils';

const dataSelector = createSelector(
    state => state.getIn(['page', 'domainData', 'categories', 'data']),
    data => {
        const result = data.toJS();
        return result.filter(item => item.status === workItemCategoryStatus.生效);
    }
);

const locatedCategorySelector = createSelector(
    state => dataSelector(state),
    state => state.getIn(['page', 'appState', 'queryHighCondition', 'workItemCategoryId']),
    (categories, locatedKey) => {
        if(!locatedKey)
            return '';
        const category = getObjById(categories, locatedKey);
        return category.id;
    }
);

const mapStateToProps = state => ({
    pages: dataSelector(state),
    locatedKey: locatedCategorySelector(state),
    loading: state.getIn(['page', 'domainData', 'categories', 'isFetching'])
});
const mapDispatchToProps = dispatch => ({
    init: () => dispatch(getTopCategories(false)),
    onSelect: id => dispatch(categoryHighSearch(id)),
    onLoadData: ({id}) => dispatch(getCategoryChildren(id)),
    onReload: () => {
        dispatch(getTopCategories(true));
        dispatch(saveHighQueryCondition('workItemCategoryId', ''));
    },
});
export default connect(mapStateToProps, mapDispatchToProps)(injectIntl(CategoryTree));
